#include "globals.h"
#include <QMessageBox>

#ifdef _WIN32
#include <windows.h>
#define OWENIO_NOT_USE_IMPORTLIB 1
#include "owen_io.h"
#include <QDebug>
#include <QDateTime>

TProcSetApiMode SetApiMode=0;
TProcOpenPort OpenPort=0;
TProcClosePort ClosePort=0;
TProcReadUInt ReadUInt=0;
TProcReadFloat24 ReadFloat=0;
TProcReadIEEE32 ReadIEEE=0;

HINSTANCE hDll=0;
#endif

CGlobals *globals;



CGlobals::~CGlobals()
{
    cleanAll();
    delete _model;
}

CGlobals::CGlobals():SMSLogFilename("sms.txt"),modem(NULL),owenInit(false)
{
#ifdef _WIN32
    qDebug("CGlobals::CGlobals enter");

   hDll = LoadLibrary(L"plugins/owen_io.dll");
   if (hDll == INVALID_HANDLE_VALUE)
   {
       QMessageBox::information(0,"Error","Cannot found OWEN_IO.dll");
       hDll =0;
   }
   else
   {

       SetApiMode = (TProcSetApiMode) GetProcAddress(hDll,(const CHAR*)"SetApiMode");
       OpenPort = (TProcOpenPort) GetProcAddress(hDll,(const CHAR*)"OpenPort");

       ClosePort = (TProcClosePort) GetProcAddress(hDll,(const CHAR*)"ClosePort");
       ReadUInt = (TProcReadUInt) GetProcAddress (hDll,(const CHAR*)"ReadUInt");

       ReadFloat = (TProcReadFloat24) GetProcAddress (hDll,(const CHAR*)"ReadFloat24");
       ReadIEEE = (TProcReadIEEE32) GetProcAddress (hDll,(const CHAR*)"ReadIEEE32");

        if (! (SetApiMode && OpenPort && ClosePort && ReadUInt && ReadFloat))
        {
            CloseHandle(hDll);
            hDll=0;
            QMessageBox::information(0,"Error","Cannot load OWEN_IO.dll");
        }
        else
        {
                 SetApiMode(OWENIO_API_NEW);
        }
    }

   _model = new MyModel;
   updateTimer.setInterval(500);
   QObject::connect(&updateTimer,SIGNAL(timeout()),this,SLOT(updateParameters()));
   QObject::connect(&updateTimer,SIGNAL(timeout()),this,SLOT(updateView()));

   qDebug("CGlobals::CGlobals exit");
#endif
}

bool CGlobals::setupModem(unsigned int baud, unsigned char port)
{
    if (modem)
    {
        queue.setModem(0);;
        queue.clear();
        delete modem;
        modem=0;
    }

    modem = new CGsmModem(baud,port);
    queue.setModem(modem);
    return true;
}

QString CGlobals::modemCmd(QString cmd)
{
    return modem->queryCommand(cmd);
};

bool CGlobals::queueAddMessage(QString message,QString recipient)
{
    queue.addMessage(message,recipient);
    QFile f(SMSLogFilename);


    QDateTime cur = QDateTime::currentDateTime();
    QString s = cur.toString("[d.MM.yy / h:mm:ss] ") +
            QString("[%1] \"%2\"\r\n").arg(recipient,message);

    f.open(QIODevice::Append | QIODevice::Text);
    f.write(s.toLocal8Bit());
    f.close();
    return true;
};

bool CGlobals::setupOwen(unsigned int baud, unsigned char port)
{
#ifdef WIN32
    qDebug("CGlobals::setupOwen enter");
    owenInit = false;
    if (!hDll)
    {
        qDebug("CGlobals::setupOwen DLL is not loaded");
        return false;
    }
    ClosePort();
    int br;
    switch (baud)
    {
    case 115200:
        br = spd_115200;
        break;

    case 19200:
        br = spd_115200;
        break;

    case 9600:
        br = spd_9600;
        break;

    default:
        br = spd_115200;
        break;
    };
    if ( 0 !=OpenPort( port - 1, br, prty_NONE, databits_8, stopbit_1, RS485CONV_AUTO) )
    {
        qDebug("CGlobals::setupOwen cannot open port");
        return false;
    }
    owenInit = true;
    qDebug("CGlobals::setupOwen successfull");
#endif
    return true;
};

CValue CGlobals::owenRead(int address)
{
#ifdef _WIN32
        if (!hDll)
        {
            qDebug("CGlobals::owenRead no hDll");
            return CValue();
        }
        if (owenInit == false)
        {
            static int send=0;
            if (send < 5)
            {
                qDebug("CGlobals::owenRead OWEN not initialized");
                send++;
            }
            return CValue();
        }

        int r;
        float f;
        int result;

        //if (!ReadIEEE) return CValue();
        result = ReadIEEE(address,ADRTYPE_8BIT,(char*)"Read",f,r,-1);
        if (result==0) return CValue(f);

        result = ReadIEEE(address,ADRTYPE_8BIT,(char*)"rEAD",f,r,-1);
        if (result==0) return CValue(f);

        return CValue();

#else
        return CValue();
#endif
}


void CGlobals::updateParameters()
{
    for (int j=0; j<15; j++)
    {
        static int iterator=0;
        if (iterator>=parameters.count()) iterator=0;
        if (parameters.count() == 0) return;
        CTechParameter *p = parameters[iterator];
        p->update();
        iterator++;
    }
}

void CGlobals::updateView()
{
    foreach(FAlarm *al, alarms)
        al->update();
     _model->update();
}


void CGlobals::cleanAll()
{
    log.setInterval(0);
    updateTimer.stop();

    foreach (FAlarm *al, alarms)
        delete al;
    alarms.clear();

    foreach(CTechParameter *p, parameters)
        delete p;
    parameters.clear();

    userBase.cleanAll();
    _model->onLoad();
}


bool CGlobals::load(QString filename)
{
    cleanAll();
    envi.load(filename);

    updateTimer.start();
    _model->onLoad();
    return true;
}
